﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

namespace TFSRequestManager
{
    /// <summary>
    /// Copied from: http://www.codeproject.com/KB/linq/LinqStatistics.aspx
    /// </summary>
    public static class EnumerableStats
    {
        public static IEnumerable<T> Coalesce<T>(this IEnumerable<T?> source) where T : struct
        {
            Debug.Assert(source != null);
            return source.Where(x => x.HasValue).Select(x => (T)x);
        }

        public static double Median(this IEnumerable<double> source)
        {
            var sortedList = from number in source
                             orderby number
                             select number;

            int count = sortedList.Count();
            int itemIndex = count / 2;

            if (count % 2 == 0)
                // Even number of items.
                return (sortedList.ElementAt(itemIndex) + sortedList.ElementAt(itemIndex - 1)) / 2;

            // Odd number of items.
            return sortedList.ElementAt(itemIndex);
        }

        public static double Variance(this IEnumerable<double> source)
        {
            double avg = source.Average();
            double d = source.Aggregate(0.0, (total, next) => total += Math.Pow(next - avg, 2));
            return d / (source.Count() - 1);
        }

        public static double VarianceP(this IEnumerable<double> source)
        {
            double avg = source.Average();
            double d = source.Aggregate(0.0, (total, next) => total += Math.Pow(next - avg, 2));
            return d / source.Count();
        }

        public static double StandardDeviation(this IEnumerable<double> source)
        {
            return Math.Sqrt(source.Variance());
        }

        public static double StandardDeviationP(this IEnumerable<double> source)
        {
            return Math.Sqrt(source.VarianceP());
        }
    }
}
